package cn.tellsea.modifier.controller;

import cn.tellsea.modifier.entity.AjaxResult;
import cn.tellsea.modifier.entity.ProjectInfo;
import cn.tellsea.modifier.utils.FileUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Tellsea
 * @date 2022/3/18
 */
@Slf4j
@Controller
public class IndexController {

    @GetMapping({"", "/", "/index"})
    public String index() {
        return "index";
    }

    static StringBuffer result = new StringBuffer();

    @PostMapping("handle")
    @ResponseBody
    public AjaxResult handle(ProjectInfo entity) {
        setResult(3, "------------------------------------------------------------> 复制项目开始");
        FileUtils.copyDir(entity.getRootPath(), entity.getRootPathTarget());
        setResult(3, "------------------------------------------------------------> 复制项目结束");
        setResult(3, "------------------------------------------------------------> 后端修改开始");
        String projectPath = entity.getRootPathTarget() + File.separator + entity.getSystemName();
        String projectPathTarget = entity.getRootPathTarget() + File.separator + entity.getSystemNameTarget();
        handleService(entity, projectPath, projectPathTarget);
        setResult(3, "------------------------------------------------------------> 后端修改结束");
        setResult(3, "------------------------------------------------------------> PC端修改开始");
        projectPath = entity.getRootPathTarget() + File.separator + entity.getPcName();
        projectPathTarget = entity.getRootPathTarget() + File.separator + entity.getPcNameTarget();
        handleService(entity, projectPath, projectPathTarget);
        setResult(3, "------------------------------------------------------------> PC端修改结束");
        setResult(3, "------------------------------------------------------------> 用户端修改开始");
        projectPath = entity.getRootPathTarget() + File.separator + entity.getUserName();
        projectPathTarget = entity.getRootPathTarget() + File.separator + entity.getUserNameTarget();
        handleService(entity, projectPath, projectPathTarget);
        setResult(3, "------------------------------------------------------------> 用户端修改结束");
        return AjaxResult.success("执行成功", result.toString());
    }

    /**
     * 执行修改
     *
     * @param entity
     * @param projectPath
     * @param projectPathTarget
     */
    public static void handleService(ProjectInfo entity, String projectPath, String projectPathTarget) {
        // 修改项目名
        new File(projectPath).renameTo(new File(projectPathTarget));
        setResult(1, "【成功】修改项目名：" + projectPath + " -> " + projectPathTarget);

        // 删除多余
        List<String> filePathList = FileUtils.getFilePathList(projectPathTarget);
        for (String filePath : filePathList) {
            // 删除多余文件夹
            for (String folder : entity.getDeleteFolderList()) {
                if (filePath.contains(File.separator + folder)) {
                    String fileName = filePath.substring(0, filePath.indexOf(folder) + folder.length());
                    File file = new File(fileName);
                    if (file.exists()) {
                        setResult(1, "【成功】删除多余文件夹：" + filePath);
                        FileUtils.deleteDirectory(fileName);
                    }
                }
            }
            // 删除多余文件
            for (String name : entity.getDeleteFileList()) {
                if (filePath.contains(name)) {
                    setResult(1, "【成功】删除多余文件：" + filePath);
                    new File(filePath).delete();
                }
            }
        }

        // 修改模块名
        filePathList = FileUtils.getFilePathList(projectPathTarget);
        Map<String, String> updateFolderMap = new HashMap<>();
        updateFolderMap.put(entity.getModelPrefix() + "-admin", entity.getModelPrefixTarget() + "-admin");
        updateFolderMap.put(entity.getModelPrefix() + "-common", entity.getModelPrefixTarget() + "-common");
        updateFolderMap.put(entity.getModelPrefix() + "-framework", entity.getModelPrefixTarget() + "-framework");
        updateFolderMap.put(entity.getModelPrefix() + "-generator", entity.getModelPrefixTarget() + "-generator");
        updateFolderMap.put(entity.getModelPrefix() + "-quartz", entity.getModelPrefixTarget() + "-quartz");
        updateFolderMap.put(entity.getModelPrefix() + "-system", entity.getModelPrefixTarget() + "-system");
        for (String filePath : filePathList) {
            File file = new File(filePath);
            if (file.isDirectory()) {
                // 修改模块名
                String fileName = filePath.substring(filePath.lastIndexOf(File.separator) + 1);
                if (updateFolderMap.containsKey(fileName)) {
                    File oldFile = new File(filePath);
                    oldFile.renameTo(new File(filePath.substring(0, filePath.lastIndexOf(File.separator) + 1) + updateFolderMap.get(fileName)));
                    setResult(1, "【成功】修改模块名：" + fileName + " -> " + updateFolderMap.get(fileName));
                }
            }
        }

        // 修改包路径
        filePathList = FileUtils.getFilePathList(projectPathTarget);
        for (String filePath : filePathList) {
            File file = new File(filePath);
            if (file.isDirectory()) {
                // 修改包路径
                if (filePath.contains(entity.getOrgName())) {
                    File oldFile = new File(filePath);
                    oldFile.renameTo(new File(filePath.replace(entity.getOrgName(), entity.getOrgNameTarget())));
                    setResult(1, "【成功】修改包路径：" + filePath + " -> " + filePath.replace(entity.getOrgName(), entity.getOrgNameTarget()));
                }
            }
        }

        // 修改文件内容
        filePathList = FileUtils.getFilePathList(projectPathTarget);
        for (String filePath : filePathList) {
            if (filePath.contains("uview-ui")) {
                continue;
            }
            File file = new File(filePath);
            if (!file.isDirectory()) {
                String suffix = filePath.substring(filePath.lastIndexOf("."));
                if (!entity.getExcludeFileSuffix().contains(suffix)) {
                    // 修改文件中的模块名
                    for (Map.Entry<String, String> entry : updateFolderMap.entrySet()) {
                        handleRow(filePath, entry.getKey(), entry.getValue());
                    }
                    handleRow(filePath, "ruoyi-vue-plus", entity.getSystemNameTarget());
                    handleRow(filePath, entity.getOrgName(), entity.getOrgNameTarget());
                    handleRow(filePath, entity.getSystemName(), entity.getSystemNameTarget());
                    handleRow(filePath, entity.getPcName(), entity.getPcNameTarget());
                    handleRow(filePath, entity.getUserName(), entity.getUserNameTarget());
                }
            }
        }
    }

    private static void handleRow(String filePath, String oldStr, String newStr) {
        try {
            File file = new File(filePath);
            FileInputStream inputStream = new FileInputStream(filePath);
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String str;
            while ((str = bufferedReader.readLine()) != null) {
                if (str.contains(oldStr)) {
                    FileUtils.updateFileRow(file, oldStr, newStr);
                    setResult(1, "【成功】修改文件内容：" + filePath);
                }
            }
            bufferedReader.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private static void setResult(int type, String msg) {
        log.info("执行：" + msg);
        if (type == 1) {
            result.append("<p style='color: green;'>" + msg + "</p>");
        } else if (type == 2) {
            result.append("<p style='color: red;'>" + msg + "</p>");
        } else {
            result.append("<p>" + msg + "</p>");

        }
    }
}
